Resumo:
Este artigo científico tem como objetivo apresentar uma análise
detalhada da base de dados “Coronavírus Brasil”, uma fonte fundamental
de informações sobre a pandemia da COVID-19 no Brasil. A base de dados é
composta por uma ampla gama de informações epidemiológicas, incluindo
casos confirmados, óbitos, datas de notificação, testes realizados e
detalhes sobre a vacinação. Neste estudo, exploraremos a estrutura, o
conteúdo e a relevância dessa base de dados para pesquisas científicas e
análises de políticas públicas relacionadas à pandemia.
Funcionamento da Plataforma “Coronavírus
Brasil”:
A plataforma “Coronavírus Brasil” é uma iniciativa governamental que
coleta, armazena e disponibiliza informações sobre a pandemia da
COVID-19 no país. Ela é mantida pelo Ministério da Saúde e pode ser
acessada por pesquisadores, profissionais de saúde e o público em geral.
Os dados são atualizados regularmente para refletir a evolução da
pandemia.
Os dados relacionados à COVID-19 na plataforma “Coronavírus Brasil”
são organizados em um formato tabular, que geralmente é representado em
um arquivo CSV (Comma-Separated Values).
No contexto deste estudo, a escolha da linguagem de programação R
para a análise da base de dados “Coronavírus Brasil” é altamente
apropriada e vantajosa. O R é uma linguagem e ambiente de programação
estatística amplamente reconhecido e utilizado por cientistas de dados,
estatísticos e pesquisadores em todo o mundo. Várias razões tornam o R
uma escolha valiosa para análises científicas, especialmente em
epidemiologia e saúde pública.
Primeiramente, o R oferece um vasto ecossistema de pacotes e
bibliotecas específicos para análise de dados e visualização, como o
`dplyr` e o `ggplot2`, que simplificam o processo de manipulação e
representação gráfica de dados. Essas ferramentas são particularmente
úteis para lidar com dados tabulares, como os presentes na base
“Coronavírus Brasil”.
A linguagem R também é conhecida por sua capacidade de produzir
gráficos e visualizações de alta qualidade, essenciais para comunicar
resultados e conclusões de forma clara e eficaz.
No contexto deste estudo sobre a pandemia da COVID-19, o R permitirá
a importação, limpeza, análise e visualização de dados de maneira
eficiente e rigorosa, contribuindo para a obtenção de insights valiosos
e para a tomada de decisões informadas. Sua capacidade de realizar
análises estatísticas avançadas, modelagem e mineração de dados também o
torna uma escolha poderosa para explorar a complexidade dos dados
epidemiológicos.
Análise de Sentimentos:
A análise de sentimentos é uma técnica que permite avaliar as emoções
e opiniões expressas em textos. Pode ser aplicada para entender como o
público percebe a pandemia. Coletando dados de redes sociais, fóruns ou
notícias relacionadas à COVID-19, podemos analisar o sentimento geral do
público em relação à pandemia, identificar tendências de preocupação ou
otimismo e até mesmo detectar desinformação.
Extração de Informação:
A extração de informações envolve a identificação e captura de
informações específicas em textos não estruturados. Na base “Coronavírus
Brasil”, podemos aplicar essa técnica para extrair dados como números de
casos, óbitos, datas de notificação e localizações geográficas dos
relatórios, tornando as informações mais acessíveis e estruturadas para
análise.
Agrupamento de Documentos:
Agrupamento de documentos é uma técnica que permite agrupar textos
semelhantes em clusters. Isso pode ser útil para identificar padrões
geográficos ou temporais na propagação da COVID-19. Ao agrupar
relatórios por estado ou mês, podemos observar tendências regionais e
sazonalidades nos dados.
Classificação de Texto:
A classificação de texto é usada para categorizar textos em classes
predefinidas. Pode ser aplicada para identificar notícias ou relatórios
de saúde pública que contenham informações imprecisas ou desatualizadas.
Isso ajuda na detecção de informações errôneas que podem ser
prejudiciais.
Descoberta de Associação:
A descoberta de associações busca encontrar padrões e relações
ocultas entre itens em conjuntos de dados. Pode ser usada para
identificar associações entre medidas de controle da pandemia, como
lockdowns ou campanhas de vacinação, e a evolução dos casos de COVID-19
em diferentes estados.
Cancelamento de Esquemas:
O cancelamento de esquemas refere-se à identificação e eliminação de
informações falsas ou desatualizadas na base de dados. Usando técnicas
de mineração de texto, podemos verificar a veracidade de informações e
marcar dados inconsistentes para posterior correção.
Coletando os de 2020 da Pandemia no Brasil e mostrando os casos que
aconteceram no pais no ano de 2020
library(readxl)
library(dplyr)
library(ggplot2)
setwd("/Users/wisley/Documents/Matéria do 4 periodo /Minereção de Texto /Trabalho Final /Minerao-De-Texto--Covid-19")
# vamos coletar os dados
# vamos manipular os dados agora
dados_covid_2020_1_semestre <- read.csv2("HIST_PAINEL_COVIDBR_2020_Parte1_03out2023.csv")
# formatando as data do primeiro bimestre
dados_covid_2020_1_semestre$data <- as.Date(dados_covid_2020_1_semestre$data, format = "%d/%m/%y")
# formatando as data do segundo bimestre
dados_covid_2020_2_semestre <-read.csv2("HIST_PAINEL_COVIDBR_2020_Parte2_03out2023.csv")
dados_covid_2020_2_semestre$data <- as.Date(dados_covid_2020_2_semestre$data, format = "%Y-%m-%d")
# juntado os dois bimestre
dados_covid_2020 <-bind_rows(dados_covid_2020_1_semestre,dados_covid_2020_2_semestre)
# colocando os dados que estão fazio como NA para facilitar a analise dos dados
dados_covid_2020$municipio[dados_covid_2020$municipio == ""] <- NA
dados_covid_2020$nomeRegiaoSaude[dados_covid_2020$nomeRegiaoSaude == ""] <- NA
dados_covid_2020$estado[dados_covid_2020$estado == ""] <- NA
#pegando os dados so do Brasil
covid.Brasil <- filter(dados_covid_2020, is.na(municipio) & is.na(codmun) & is.na(estado))
Mostrando os dados dos estados do Brasil
# pegando os dados de todos os estados
covid.estados <- filter(dados_covid_2020, is.na(municipio) & is.na(codmun) & !is.na(estado))
Analisando todos os estado separadamente
Estado do Acre
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
Attaching package: ‘gridExtra’
The following object is masked from ‘package:dplyr’:
combine
# Filtre os dados para o estado do Acre e renomeie as colunas
covid_ac_2020 <- covid.estados %>%
filter(estado == "AC") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ac_2020 <- covid_ac_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ac_resumo <- covid_ac_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ac_resumo, casosNovos, "Casos Novos de COVID-19 no Acre por Mês", "Casos Novos")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.
grafico_obitos <- criar_grafico(covid_ac_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Acre por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
NA
Estado do Alagoas
# Filtre os dados para o estado de Alagoas e renomeie as colunas
covid_al_2020 <- covid.estados %>%
filter(estado == "AL") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_al_2020 <- covid_al_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_al_resumo <- covid_al_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_al_resumo, casosNovos, "Casos Novos de COVID-19 em Alagoas por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_al_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Alagoas por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Amazonas
# Filtre os dados para o estado do Amazonas e renomeie as colunas
covid_am_2020 <- covid.estados %>%
filter(estado == "AM") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_am_2020 <- covid_am_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_am_resumo <- covid_am_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_am_resumo, casosNovos, "Casos Novos de COVID-19 no Amazonas por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_am_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Amazonas por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Amapá
# Filtre os dados para o estado do Amapá e renomeie as colunas
covid_ap_2020 <- covid.estados %>%
filter(estado == "AP") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ap_2020 <- covid_ap_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ap_resumo <- covid_ap_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ap_resumo, casosNovos, "Casos Novos de COVID-19 no Amapá por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ap_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Amapá por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Bahia
#Bahia
# Filtre os dados para o estado da Bahia e renomeie as colunas
covid_ba_2020 <- covid.estados %>%
filter(estado == "BA") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ba_2020 <- covid_ba_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ba_resumo <- covid_ba_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ba_resumo, casosNovos, "Casos Novos de COVID-19 na Bahia por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ba_resumo, obitosNovos, "Óbitos Novos de COVID-19 na Bahia por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Ceará
# Filtre os dados para o estado do Ceará e renomeie as colunas
covid_ce_2020 <- covid.estados %>%
filter(estado == "CE") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ce_2020 <- covid_ce_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ce_resumo <- covid_ce_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ce_resumo, casosNovos, "Casos Novos de COVID-19 no Ceará por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ce_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Ceará por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Distrito Federal
# Filtre os dados para o Distrito Federal e renomeie as colunas
covid_df_2020 <- covid.estados %>%
filter(estado == "DF") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_df_2020 <- covid_df_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_df_resumo <- covid_df_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_df_resumo, casosNovos, "Casos Novos de COVID-19 no Distrito Federal por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_df_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Distrito Federal por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Espírito Santo
#Espírito Santo
# Filtre os dados para o estado do Espírito Santo e renomeie as colunas
covid_es_2020 <- covid.estados %>%
filter(estado == "ES") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_es_2020 <- covid_es_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_es_resumo <- covid_es_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_es_resumo, casosNovos, "Casos Novos de COVID-19 no Espírito Santo por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_es_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Espírito Santo por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Goiás
# Filtre os dados para o estado de Goiás e renomeie as colunas
covid_go_2020 <- covid.estados %>%
filter(estado == "GO") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_go_2020 <- covid_go_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_go_resumo <- covid_go_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_go_resumo, casosNovos, "Casos Novos de COVID-19 em Goiás por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_go_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Goiás por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Maranhão
#Maranhão
# Filtre os dados para o estado do Maranhão e renomeie as colunas
covid_ma_2020 <- covid.estados %>%
filter(estado == "MA") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ma_2020 <- covid_ma_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ma_resumo <- covid_ma_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ma_resumo, casosNovos, "Casos Novos de COVID-19 no Maranhão por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ma_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Maranhão por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Minas Gerais
#Minas Gerais
# Crie colunas para o ano e o mês
covid_ma_2020 <- covid_ma_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ma_resumo <- covid_ma_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ma_resumo, casosNovos, "Casos Novos de COVID-19 no Maranhão por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ma_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Maranhão por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Mato Grosso do Sul
# Filtre os dados para o estado de Mato Grosso do Sul e renomeie as colunas
covid_ms_2020 <- covid.estados %>%
filter(estado == "MS") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ms_2020 <- covid_ms_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ms_resumo <- covid_ms_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ms_resumo, casosNovos, "Casos Novos de COVID-19 em Mato Grosso do Sul por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ms_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Mato Grosso do Sul por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Mato Grosso
#Mato Grosso
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Mato Grosso e renomeie as colunas
covid_mt_2020 <- covid.estados %>%
filter(estado == "MT") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_mt_2020 <- covid_mt_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_mt_resumo <- covid_mt_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_mt_resumo, casosNovos, "Casos Novos de COVID-19 em Mato Grosso por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_mt_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Mato Grosso por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Pará
#Pará
# Filtre os dados para o estado do Pará e renomeie as colunas
covid_pa_2020 <- covid.estados %>%
filter(estado == "PA") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_pa_2020 <- covid_pa_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pa_resumo <- covid_pa_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_pa_resumo, casosNovos, "Casos Novos de COVID-19 no Pará por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pa_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Pará por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
Estado do Paraíba
# Filtre os dados para o estado da Paraíba e renomeie as colunas
covid_pb_2020 <- covid.estados %>%
filter(estado == "PB") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format = "%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_pb_2020 <- covid_pb_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pb_resumo <- covid_pb_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_pb_resumo, casosNovos, "Casos Novos de COVID-19 na Paraíba por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pb_resumo, obitosNovos, "Óbitos Novos de COVID-19 na Paraíba por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Pernambuco
# Pernambuco
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Pernambuco e renomeie as colunas
covid_pe_2020 <- covid.estados %>%
filter(estado == "PE") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_pe_2020 <- covid_pe_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pe_resumo <- covid_pe_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_pe_resumo, casosNovos, "Casos Novos de COVID-19 em Pernambuco por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pe_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Pernambuco por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
Estado do Piauí
#Piauí
# Filtre os dados para o estado do Piauí e renomeie as colunas
covid_pi_2020 <- covid.estados %>%
filter(estado == "PI") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_pi_2020 <- covid_pi_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pi_resumo <- covid_pi_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_pi_resumo, casosNovos, "Casos Novos de COVID-19 no Piauí por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pi_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Piauí por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Paraná
#Paraná
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado do Paraná e renomeie as colunas
covid_pr_2020 <- covid.estados %>%
filter(estado == "PR") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_pr_2020 <- covid_pr_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pr_resumo <- covid_pr_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_pr_resumo, casosNovos, "Casos Novos de COVID-19 no Paraná por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pr_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Paraná por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rio de Janeiro
# Rio De Janeiro
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado do Rio de Janeiro e renomeie as colunas
covid_rj_2020 <- covid.estados %>%
filter(estado == "RJ") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_rj_2020 <- covid_rj_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rj_resumo <- covid_rj_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_rj_resumo, casosNovos, "Casos Novos de COVID-19 no Rio de Janeiro por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rj_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio de Janeiro por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
Estado do Rio Grande do Norte
#Rio Grande Do Norte
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado do Rio Grande do Norte e renomeie as colunas
covid_rn_2020 <- covid.estados %>%
filter(estado == "RN") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_rn_2020 <- covid_rn_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rn_resumo <- covid_rn_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_rn_resumo, casosNovos, "Casos Novos de COVID-19 no Rio Grande do Norte por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rn_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio Grande do Norte por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rondônia
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Rondônia e renomeie as colunas
covid_ro_2020 <- covid.estados %>%
filter(estado == "RO") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_ro_2020 <- covid_ro_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ro_resumo <- covid_ro_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_ro_resumo, casosNovos, "Casos Novos de COVID-19 em Rondônia por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ro_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Rondônia por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
Estado do Roraima
#Roriama
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Roraima e renomeie as colunas
covid_rr_2020 <- covid.estados %>%
filter(estado == "RR") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_rr_2020 <- covid_rr_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rr_resumo <- covid_rr_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_rr_resumo, casosNovos, "Casos Novos de COVID-19 em Roraima por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rr_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Roraima por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rio Grande do Sul
#Rio Grande Do Sul
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado do Rio Grande do Sul e renomeie as colunas
covid_rs_2020 <- covid.estados %>%
filter(estado == "RS") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_rs_2020 <- covid_rs_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rs_resumo <- covid_rs_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_rs_resumo, casosNovos, "Casos Novos de COVID-19 no Rio Grande do Sul por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rs_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio Grande do Sul por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Santa Catarina
#Santa Catarina
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Santa Catarina e renomeie as colunas
covid_sc_2020 <- covid.estados %>%
filter(estado == "SC") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_sc_2020 <- covid_sc_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_sc_resumo <- covid_sc_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_sc_resumo, casosNovos, "Casos Novos de COVID-19 em Santa Catarina por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_sc_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Santa Catarina por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Sergipe
# Sergipe
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Sergipe e renomeie as colunas
covid_se_2020 <- covid.estados %>%
filter(estado == "SE") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_se_2020 <- covid_se_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_se_resumo <- covid_se_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_se_resumo, casosNovos, "Casos Novos de COVID-19 em Sergipe por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_se_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Sergipe por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do São Paulo
# São Paulo
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de São Paulo e renomeie as colunas
covid_sp_2020 <- covid.estados %>%
filter(estado == "SP") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_sp_2020 <- covid_sp_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_sp_resumo <- covid_sp_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_sp_resumo, casosNovos, "Casos Novos de COVID-19 em São Paulo por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_sp_resumo, obitosNovos, "Óbitos Novos de COVID-19 em São Paulo por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Tocantins
#Tocantins
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtre os dados para o estado de Tocantins e renomeie as colunas
covid_to_2020 <- covid.estados %>%
filter(estado == "TO") %>%
select(data, casosNovos, obitosNovos) %>%
mutate(data = as.Date(data, format="%Y-%m-%d"))
# Crie colunas para o ano e o mês
covid_to_2020 <- covid_to_2020 %>%
mutate(ano = lubridate::year(data),
mes = lubridate::month(data))
# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_to_resumo <- covid_to_2020 %>%
group_by(ano, mes) %>%
summarise(casosNovos = sum(casosNovos),
obitosNovos = sum(obitosNovos), .groups = 'drop_last')
# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
labs(title = titulo,
x = "Mês",
y = ylab) +
theme_minimal()
}
# Crie gráficos
grafico_casos <- criar_grafico(covid_to_resumo, casosNovos, "Casos Novos de COVID-19 em Tocantins por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_to_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Tocantins por Mês", "Óbitos Novos")
# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

LS0tCnRpdGxlOiAiVGVuZMOqbmNpYXMgRXBpZGVtaW9sw7NnaWNhcyBkYSBDT1ZJRC0xOSBubyBCcmFzaWw6IEltcGFjdG8gZGEgVmFjaW5hw6fDo28gbm9zIENhc29zIGUgw5NiaXRvcyBwb3IgRXN0YWRvIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgUmVzdW1vOgoKRXN0ZSBhcnRpZ28gY2llbnTDrWZpY28gdGVtIGNvbW8gb2JqZXRpdm8gYXByZXNlbnRhciB1bWEgYW7DoWxpc2UgZGV0YWxoYWRhIGRhIGJhc2UgZGUgZGFkb3MgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLCB1bWEgZm9udGUgZnVuZGFtZW50YWwgZGUgaW5mb3JtYcOnw7VlcyBzb2JyZSBhIHBhbmRlbWlhIGRhIENPVklELTE5IG5vIEJyYXNpbC4gQSBiYXNlIGRlIGRhZG9zIMOpIGNvbXBvc3RhIHBvciB1bWEgYW1wbGEgZ2FtYSBkZSBpbmZvcm1hw6fDtWVzIGVwaWRlbWlvbMOzZ2ljYXMsIGluY2x1aW5kbyBjYXNvcyBjb25maXJtYWRvcywgw7NiaXRvcywgZGF0YXMgZGUgbm90aWZpY2HDp8OjbywgdGVzdGVzIHJlYWxpemFkb3MgZSBkZXRhbGhlcyBzb2JyZSBhIHZhY2luYcOnw6NvLiBOZXN0ZSBlc3R1ZG8sIGV4cGxvcmFyZW1vcyBhIGVzdHJ1dHVyYSwgbyBjb250ZcO6ZG8gZSBhIHJlbGV2w6JuY2lhIGRlc3NhIGJhc2UgZGUgZGFkb3MgcGFyYSBwZXNxdWlzYXMgY2llbnTDrWZpY2FzIGUgYW7DoWxpc2VzIGRlIHBvbMOtdGljYXMgcMO6YmxpY2FzIHJlbGFjaW9uYWRhcyDDoCBwYW5kZW1pYS4KCioqRnVuY2lvbmFtZW50byBkYSBQbGF0YWZvcm1hICJDb3JvbmF2w61ydXMgQnJhc2lsIjoqKgoKQSBwbGF0YWZvcm1hICJDb3JvbmF2w61ydXMgQnJhc2lsIiDDqSB1bWEgaW5pY2lhdGl2YSBnb3Zlcm5hbWVudGFsIHF1ZSBjb2xldGEsIGFybWF6ZW5hIGUgZGlzcG9uaWJpbGl6YSBpbmZvcm1hw6fDtWVzIHNvYnJlIGEgcGFuZGVtaWEgZGEgQ09WSUQtMTkgbm8gcGHDrXMuIEVsYSDDqSBtYW50aWRhIHBlbG8gTWluaXN0w6lyaW8gZGEgU2HDumRlIGUgcG9kZSBzZXIgYWNlc3NhZGEgcG9yIHBlc3F1aXNhZG9yZXMsIHByb2Zpc3Npb25haXMgZGUgc2HDumRlIGUgbyBww7pibGljbyBlbSBnZXJhbC4gT3MgZGFkb3Mgc8OjbyBhdHVhbGl6YWRvcyByZWd1bGFybWVudGUgcGFyYSByZWZsZXRpciBhIGV2b2x1w6fDo28gZGEgcGFuZGVtaWEuCgpPcyBkYWRvcyByZWxhY2lvbmFkb3Mgw6AgQ09WSUQtMTkgbmEgcGxhdGFmb3JtYSAiQ29yb25hdsOtcnVzIEJyYXNpbCIgc8OjbyBvcmdhbml6YWRvcyBlbSB1bSBmb3JtYXRvIHRhYnVsYXIsIHF1ZSBnZXJhbG1lbnRlIMOpIHJlcHJlc2VudGFkbyBlbSB1bSBhcnF1aXZvIENTViAoQ29tbWEtU2VwYXJhdGVkIFZhbHVlcykuCgpObyBjb250ZXh0byBkZXN0ZSBlc3R1ZG8sIGEgZXNjb2xoYSBkYSBsaW5ndWFnZW0gZGUgcHJvZ3JhbWHDp8OjbyBSIHBhcmEgYSBhbsOhbGlzZSBkYSBiYXNlIGRlIGRhZG9zICJDb3JvbmF2w61ydXMgQnJhc2lsIiDDqSBhbHRhbWVudGUgYXByb3ByaWFkYSBlIHZhbnRham9zYS4gTyBSIMOpIHVtYSBsaW5ndWFnZW0gZSBhbWJpZW50ZSBkZSBwcm9ncmFtYcOnw6NvIGVzdGF0w61zdGljYSBhbXBsYW1lbnRlIHJlY29uaGVjaWRvIGUgdXRpbGl6YWRvIHBvciBjaWVudGlzdGFzIGRlIGRhZG9zLCBlc3RhdMOtc3RpY29zIGUgcGVzcXVpc2Fkb3JlcyBlbSB0b2RvIG8gbXVuZG8uIFbDoXJpYXMgcmF6w7VlcyB0b3JuYW0gbyBSIHVtYSBlc2NvbGhhIHZhbGlvc2EgcGFyYSBhbsOhbGlzZXMgY2llbnTDrWZpY2FzLCBlc3BlY2lhbG1lbnRlIGVtIGVwaWRlbWlvbG9naWEgZSBzYcO6ZGUgcMO6YmxpY2EuCgpQcmltZWlyYW1lbnRlLCBvIFIgb2ZlcmVjZSB1bSB2YXN0byBlY29zc2lzdGVtYSBkZSBwYWNvdGVzIGUgYmlibGlvdGVjYXMgZXNwZWPDrWZpY29zIHBhcmEgYW7DoWxpc2UgZGUgZGFkb3MgZSB2aXN1YWxpemHDp8OjbywgY29tbyBvIFxgZHBseXJcYCBlIG8gXGBnZ3Bsb3QyXGAsIHF1ZSBzaW1wbGlmaWNhbSBvIHByb2Nlc3NvIGRlIG1hbmlwdWxhw6fDo28gZSByZXByZXNlbnRhw6fDo28gZ3LDoWZpY2EgZGUgZGFkb3MuIEVzc2FzIGZlcnJhbWVudGFzIHPDo28gcGFydGljdWxhcm1lbnRlIMO6dGVpcyBwYXJhIGxpZGFyIGNvbSBkYWRvcyB0YWJ1bGFyZXMsIGNvbW8gb3MgcHJlc2VudGVzIG5hIGJhc2UgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLgoKQSBsaW5ndWFnZW0gUiB0YW1iw6ltIMOpIGNvbmhlY2lkYSBwb3Igc3VhIGNhcGFjaWRhZGUgZGUgcHJvZHV6aXIgZ3LDoWZpY29zIGUgdmlzdWFsaXphw6fDtWVzIGRlIGFsdGEgcXVhbGlkYWRlLCBlc3NlbmNpYWlzIHBhcmEgY29tdW5pY2FyIHJlc3VsdGFkb3MgZSBjb25jbHVzw7VlcyBkZSBmb3JtYSBjbGFyYSBlIGVmaWNhei4KCk5vIGNvbnRleHRvIGRlc3RlIGVzdHVkbyBzb2JyZSBhIHBhbmRlbWlhIGRhIENPVklELTE5LCBvIFIgcGVybWl0aXLDoSBhIGltcG9ydGHDp8OjbywgbGltcGV6YSwgYW7DoWxpc2UgZSB2aXN1YWxpemHDp8OjbyBkZSBkYWRvcyBkZSBtYW5laXJhIGVmaWNpZW50ZSBlIHJpZ29yb3NhLCBjb250cmlidWluZG8gcGFyYSBhIG9idGVuw6fDo28gZGUgaW5zaWdodHMgdmFsaW9zb3MgZSBwYXJhIGEgdG9tYWRhIGRlIGRlY2lzw7VlcyBpbmZvcm1hZGFzLiBTdWEgY2FwYWNpZGFkZSBkZSByZWFsaXphciBhbsOhbGlzZXMgZXN0YXTDrXN0aWNhcyBhdmFuw6dhZGFzLCBtb2RlbGFnZW0gZSBtaW5lcmHDp8OjbyBkZSBkYWRvcyB0YW1iw6ltIG8gdG9ybmEgdW1hIGVzY29saGEgcG9kZXJvc2EgcGFyYSBleHBsb3JhciBhIGNvbXBsZXhpZGFkZSBkb3MgZGFkb3MgZXBpZGVtaW9sw7NnaWNvcy4KCioqQW7DoWxpc2UgZGUgU2VudGltZW50b3M6KioKCkEgYW7DoWxpc2UgZGUgc2VudGltZW50b3Mgw6kgdW1hIHTDqWNuaWNhIHF1ZSBwZXJtaXRlIGF2YWxpYXIgYXMgZW1vw6fDtWVzIGUgb3BpbmnDtWVzIGV4cHJlc3NhcyBlbSB0ZXh0b3MuIFBvZGUgc2VyIGFwbGljYWRhIHBhcmEgZW50ZW5kZXIgY29tbyBvIHDDumJsaWNvIHBlcmNlYmUgYSBwYW5kZW1pYS4gQ29sZXRhbmRvIGRhZG9zIGRlIHJlZGVzIHNvY2lhaXMsIGbDs3J1bnMgb3Ugbm90w61jaWFzIHJlbGFjaW9uYWRhcyDDoCBDT1ZJRC0xOSwgcG9kZW1vcyBhbmFsaXNhciBvIHNlbnRpbWVudG8gZ2VyYWwgZG8gcMO6YmxpY28gZW0gcmVsYcOnw6NvIMOgIHBhbmRlbWlhLCBpZGVudGlmaWNhciB0ZW5kw6puY2lhcyBkZSBwcmVvY3VwYcOnw6NvIG91IG90aW1pc21vIGUgYXTDqSBtZXNtbyBkZXRlY3RhciBkZXNpbmZvcm1hw6fDo28uCgoqKkV4dHJhw6fDo28gZGUgSW5mb3JtYcOnw6NvOioqCgpBIGV4dHJhw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBlbnZvbHZlIGEgaWRlbnRpZmljYcOnw6NvIGUgY2FwdHVyYSBkZSBpbmZvcm1hw6fDtWVzIGVzcGVjw61maWNhcyBlbSB0ZXh0b3MgbsOjbyBlc3RydXR1cmFkb3MuIE5hIGJhc2UgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLCBwb2RlbW9zIGFwbGljYXIgZXNzYSB0w6ljbmljYSBwYXJhIGV4dHJhaXIgZGFkb3MgY29tbyBuw7ptZXJvcyBkZSBjYXNvcywgw7NiaXRvcywgZGF0YXMgZGUgbm90aWZpY2HDp8OjbyBlIGxvY2FsaXphw6fDtWVzIGdlb2dyw6FmaWNhcyBkb3MgcmVsYXTDs3Jpb3MsIHRvcm5hbmRvIGFzIGluZm9ybWHDp8O1ZXMgbWFpcyBhY2Vzc8OtdmVpcyBlIGVzdHJ1dHVyYWRhcyBwYXJhIGFuw6FsaXNlLgoKKipBZ3J1cGFtZW50byBkZSBEb2N1bWVudG9zOioqCgpBZ3J1cGFtZW50byBkZSBkb2N1bWVudG9zIMOpIHVtYSB0w6ljbmljYSBxdWUgcGVybWl0ZSBhZ3J1cGFyIHRleHRvcyBzZW1lbGhhbnRlcyBlbSBjbHVzdGVycy4gSXNzbyBwb2RlIHNlciDDunRpbCBwYXJhIGlkZW50aWZpY2FyIHBhZHLDtWVzIGdlb2dyw6FmaWNvcyBvdSB0ZW1wb3JhaXMgbmEgcHJvcGFnYcOnw6NvIGRhIENPVklELTE5LiBBbyBhZ3J1cGFyIHJlbGF0w7NyaW9zIHBvciBlc3RhZG8gb3UgbcOqcywgcG9kZW1vcyBvYnNlcnZhciB0ZW5kw6puY2lhcyByZWdpb25haXMgZSBzYXpvbmFsaWRhZGVzIG5vcyBkYWRvcy4KCioqQ2xhc3NpZmljYcOnw6NvIGRlIFRleHRvOioqCgpBIGNsYXNzaWZpY2HDp8OjbyBkZSB0ZXh0byDDqSB1c2FkYSBwYXJhIGNhdGVnb3JpemFyIHRleHRvcyBlbSBjbGFzc2VzIHByZWRlZmluaWRhcy4gUG9kZSBzZXIgYXBsaWNhZGEgcGFyYSBpZGVudGlmaWNhciBub3TDrWNpYXMgb3UgcmVsYXTDs3Jpb3MgZGUgc2HDumRlIHDDumJsaWNhIHF1ZSBjb250ZW5oYW0gaW5mb3JtYcOnw7VlcyBpbXByZWNpc2FzIG91IGRlc2F0dWFsaXphZGFzLiBJc3NvIGFqdWRhIG5hIGRldGVjw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBlcnLDtG5lYXMgcXVlIHBvZGVtIHNlciBwcmVqdWRpY2lhaXMuCgoqKkRlc2NvYmVydGEgZGUgQXNzb2NpYcOnw6NvOioqCgpBIGRlc2NvYmVydGEgZGUgYXNzb2NpYcOnw7VlcyBidXNjYSBlbmNvbnRyYXIgcGFkcsO1ZXMgZSByZWxhw6fDtWVzIG9jdWx0YXMgZW50cmUgaXRlbnMgZW0gY29uanVudG9zIGRlIGRhZG9zLiBQb2RlIHNlciB1c2FkYSBwYXJhIGlkZW50aWZpY2FyIGFzc29jaWHDp8O1ZXMgZW50cmUgbWVkaWRhcyBkZSBjb250cm9sZSBkYSBwYW5kZW1pYSwgY29tbyBsb2NrZG93bnMgb3UgY2FtcGFuaGFzIGRlIHZhY2luYcOnw6NvLCBlIGEgZXZvbHXDp8OjbyBkb3MgY2Fzb3MgZGUgQ09WSUQtMTkgZW0gZGlmZXJlbnRlcyBlc3RhZG9zLgoKKipDYW5jZWxhbWVudG8gZGUgRXNxdWVtYXM6KioKCk8gY2FuY2VsYW1lbnRvIGRlIGVzcXVlbWFzIHJlZmVyZS1zZSDDoCBpZGVudGlmaWNhw6fDo28gZSBlbGltaW5hw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBmYWxzYXMgb3UgZGVzYXR1YWxpemFkYXMgbmEgYmFzZSBkZSBkYWRvcy4gVXNhbmRvIHTDqWNuaWNhcyBkZSBtaW5lcmHDp8OjbyBkZSB0ZXh0bywgcG9kZW1vcyB2ZXJpZmljYXIgYSB2ZXJhY2lkYWRlIGRlIGluZm9ybWHDp8O1ZXMgZSBtYXJjYXIgZGFkb3MgaW5jb25zaXN0ZW50ZXMgcGFyYSBwb3N0ZXJpb3IgY29ycmXDp8Ojby4KCkNvbGV0YW5kbyBvcyBkZSAyMDIwIGRhIFBhbmRlbWlhIG5vIEJyYXNpbCBlIG1vc3RyYW5kbyBvcyBjYXNvcyBxdWUgYWNvbnRlY2VyYW0gbm8gcGFpcyBubyBhbm8gZGUgMjAyMAoKYGBge3J9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCgojc2V0YW5kbyBvIG5vc3NvIHJlcG9zaXRvcmlvIApzZXR3ZCgiL1VzZXJzL3dpc2xleS9Eb2N1bWVudHMvTWF0ZcyBcmlhIGRvIDQgcGVyaW9kbyAvTWluZXJlY8ynYcyDbyBkZSBUZXh0byAvVHJhYmFsaG8gRmluYWwgL01pbmVyYW8tRGUtVGV4dG8tLUNvdmlkLTE5IikKIyB2YW1vcyBjb2xldGFyIG9zIGRhZG9zIAoKIyB2YW1vcyBtYW5pcHVsYXIgb3MgZGFkb3MgYWdvcmEgCgpkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUgPC0gcmVhZC5jc3YyKCJISVNUX1BBSU5FTF9DT1ZJREJSXzIwMjBfUGFydGUxXzAzb3V0MjAyMy5jc3YiKQojIGZvcm1hdGFuZG8gYXMgZGF0YSBkbyBwcmltZWlybyBiaW1lc3RyZSAKZGFkb3NfY292aWRfMjAyMF8xX3NlbWVzdHJlJGRhdGEgPC0gYXMuRGF0ZShkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUkZGF0YSwgZm9ybWF0ID0gIiVkLyVtLyV5IikKCiMgZm9ybWF0YW5kbyBhcyBkYXRhIGRvIHNlZ3VuZG8gYmltZXN0cmUgCmRhZG9zX2NvdmlkXzIwMjBfMl9zZW1lc3RyZSA8LXJlYWQuY3N2MigiSElTVF9QQUlORUxfQ09WSURCUl8yMDIwX1BhcnRlMl8wM291dDIwMjMuY3N2IikKZGFkb3NfY292aWRfMjAyMF8yX3NlbWVzdHJlJGRhdGEgPC0gYXMuRGF0ZShkYWRvc19jb3ZpZF8yMDIwXzJfc2VtZXN0cmUkZGF0YSwgZm9ybWF0ID0gIiVZLSVtLSVkIikKCgojIGp1bnRhZG8gb3MgZG9pcyBiaW1lc3RyZSAKZGFkb3NfY292aWRfMjAyMCA8LWJpbmRfcm93cyhkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUsZGFkb3NfY292aWRfMjAyMF8yX3NlbWVzdHJlKQoKIyBjb2xvY2FuZG8gb3MgZGFkb3MgcXVlIGVzdMOjbyBmYXppbyBjb21vIE5BIHBhcmEgZmFjaWxpdGFyIGEgYW5hbGlzZSBkb3MgZGFkb3MKZGFkb3NfY292aWRfMjAyMCRtdW5pY2lwaW9bZGFkb3NfY292aWRfMjAyMCRtdW5pY2lwaW8gPT0gIiJdIDwtIE5BCgpkYWRvc19jb3ZpZF8yMDIwJG5vbWVSZWdpYW9TYXVkZVtkYWRvc19jb3ZpZF8yMDIwJG5vbWVSZWdpYW9TYXVkZSA9PSAiIl0gPC0gTkEKCmRhZG9zX2NvdmlkXzIwMjAkZXN0YWRvW2RhZG9zX2NvdmlkXzIwMjAkZXN0YWRvID09ICIiXSA8LSBOQQojcGVnYW5kbyBvcyBkYWRvcyBzbyBkbyBCcmFzaWwgCmNvdmlkLkJyYXNpbCA8LSBmaWx0ZXIoZGFkb3NfY292aWRfMjAyMCwgaXMubmEobXVuaWNpcGlvKSAmIGlzLm5hKGNvZG11bikgJiBpcy5uYShlc3RhZG8pKQoKCmBgYAoKTW9zdHJhbmRvIG9zIGRhZG9zIGRvcyBlc3RhZG9zIGRvIEJyYXNpbAoKYGBge3J9CiMgcGVnYW5kbyBvcyBkYWRvcyBkZSB0b2RvcyBvcyBlc3RhZG9zIApjb3ZpZC5lc3RhZG9zIDwtIGZpbHRlcihkYWRvc19jb3ZpZF8yMDIwLCBpcy5uYShtdW5pY2lwaW8pICYgaXMubmEoY29kbXVuKSAmICFpcy5uYShlc3RhZG8pKQpgYGAKCkFuYWxpc2FuZG8gdG9kb3Mgb3MgZXN0YWRvIHNlcGFyYWRhbWVudGUKCkVzdGFkbyBkbyBBY3JlCgpgYGB7cn0KIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gQWNyZSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfYWNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIkFDIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9hY18yMDIwIDwtIGNvdmlkX2FjXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfYWNfcmVzdW1vIDwtIGNvdmlkX2FjXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYWNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQWNyZSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYWNfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQWNyZSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKCmBgYApFc3RhZG8gZG8gQWxhZ29hcwpgYGB7cn0KCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIEFsYWdvYXMgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2FsXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJBTCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYWxfMjAyMCA8LSBjb3ZpZF9hbF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2FsX3Jlc3VtbyA8LSBjb3ZpZF9hbF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FsX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IGVtIEFsYWdvYXMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FsX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIEFsYWdvYXMgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gQW1hem9uYXMKYGBge3J9CgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRvIEFtYXpvbmFzIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9hbV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiQU0iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2FtXzIwMjAgPC0gY292aWRfYW1fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9hbV9yZXN1bW8gPC0gY292aWRfYW1fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9hbV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBBbWF6b25hcyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYW1fcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQW1hem9uYXMgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gQW1hcMOhCmBgYHtyfQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBBbWFww6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2FwXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJBUCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYXBfMjAyMCA8LSBjb3ZpZF9hcF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2FwX3Jlc3VtbyA8LSBjb3ZpZF9hcF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FwX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIEFtYXDDoSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYXBfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQW1hcMOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIEJhaGlhCmBgYHtyfQojQmFoaWEKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGEgQmFoaWEgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2JhXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJCQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYmFfMjAyMCA8LSBjb3ZpZF9iYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2JhX3Jlc3VtbyA8LSBjb3ZpZF9iYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2JhX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5hIEJhaGlhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9iYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBuYSBCYWhpYSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCkVzdGFkbyBkbyBDZWFyw6EKYGBge3J9CgoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBDZWFyw6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2NlXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJDRSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfY2VfMjAyMCA8LSBjb3ZpZF9jZV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2NlX3Jlc3VtbyA8LSBjb3ZpZF9jZV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2NlX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIENlYXLDoSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfY2VfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQ2VhcsOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIERpc3RyaXRvIEZlZGVyYWwKCmBgYHtyfQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIERpc3RyaXRvIEZlZGVyYWwgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2RmXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJERiIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfZGZfMjAyMCA8LSBjb3ZpZF9kZl8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2RmX3Jlc3VtbyA8LSBjb3ZpZF9kZl8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2RmX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIERpc3RyaXRvIEZlZGVyYWwgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2RmX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIERpc3RyaXRvIEZlZGVyYWwgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gRXNww61yaXRvIFNhbnRvCmBgYHtyfQojRXNww61yaXRvIFNhbnRvCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gRXNww61yaXRvIFNhbnRvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9lc18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiRVMiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2VzXzIwMjAgPC0gY292aWRfZXNfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9lc19yZXN1bW8gPC0gY292aWRfZXNfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9lc19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBFc3DDrXJpdG8gU2FudG8gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2VzX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIEVzcMOtcml0byBTYW50byBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIEdvacOhcwoKYGBge3J9CiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgR29pw6FzIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9nb18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiR08iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2dvXzIwMjAgPC0gY292aWRfZ29fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9nb19yZXN1bW8gPC0gY292aWRfZ29fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9nb19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBHb2nDoXMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2dvX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIEdvacOhcyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIE1hcmFuaMOjbwoKYGBge3J9CiNNYXJhbmjDo28KIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBNYXJhbmjDo28gZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX21hXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJNQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfbWFfMjAyMCA8LSBjb3ZpZF9tYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX21hX3Jlc3VtbyA8LSBjb3ZpZF9tYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX21hX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIE1hcmFuaMOjbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbWFfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gTWFyYW5ow6NvIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKYGBgCgpFc3RhZG8gZG8gTWluYXMgR2VyYWlzCgoKYGBge3J9CiNNaW5hcyBHZXJhaXMKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9tYV8yMDIwIDwtIGNvdmlkX21hXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfbWFfcmVzdW1vIDwtIGNvdmlkX21hXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbWFfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gTWFyYW5ow6NvIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBNYXJhbmjDo28gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQpgYGAKCkVzdGFkbyBkbyBNYXRvIEdyb3NzbyBkbyBTdWwKCmBgYHtyfQojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIE1hdG8gR3Jvc3NvIGRvIFN1bCBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfbXNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIk1TIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9tc18yMDIwIDwtIGNvdmlkX21zXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfbXNfcmVzdW1vIDwtIGNvdmlkX21zXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbXNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gTWF0byBHcm9zc28gZG8gU3VsIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tc19yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBNYXRvIEdyb3NzbyBkbyBTdWwgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gTWF0byBHcm9zc28KCmBgYHtyfQojTWF0byBHcm9zc28gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIE1hdG8gR3Jvc3NvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9tdF8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiTVQiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX210XzIwMjAgPC0gY292aWRfbXRfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9tdF9yZXN1bW8gPC0gY292aWRfbXRfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tdF9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBNYXRvIEdyb3NzbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbXRfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gTWF0byBHcm9zc28gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gUGFyw6EKCgpgYGB7cn0KI1BhcsOhCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gUGFyw6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX3BhXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJQQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfcGFfMjAyMCA8LSBjb3ZpZF9wYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX3BhX3Jlc3VtbyA8LSBjb3ZpZF9wYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3BhX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIFBhcsOhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXLDoSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKYGBgCgpFc3RhZG8gZG8gUGFyYcOtYmEKCmBgYHtyfQogIAoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkYSBQYXJhw61iYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcGJfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlBCIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0ID0gIiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3BiXzIwMjAgPC0gY292aWRfcGJfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9wYl9yZXN1bW8gPC0gY292aWRfcGJfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wYl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBuYSBQYXJhw61iYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGJfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbmEgUGFyYcOtYmEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gUGVybmFtYnVjbwoKCmBgYHtyfQojIFBlcm5hbWJ1Y28KIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgUGVybmFtYnVjbyBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcGVfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlBFIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9wZV8yMDIwIDwtIGNvdmlkX3BlXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcGVfcmVzdW1vIDwtIGNvdmlkX3BlXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGVfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUGVybmFtYnVjbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGVfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUGVybmFtYnVjbyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKYGBgCgpFc3RhZG8gZG8gUGlhdcOtCgoKYGBge3J9CiNQaWF1w60gCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gUGlhdcOtIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9waV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUEkiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3BpXzIwMjAgPC0gY292aWRfcGlfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9waV9yZXN1bW8gPC0gY292aWRfcGlfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9waV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQaWF1w60gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3BpX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIFBpYXXDrSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIFBhcmFuw6EKCmBgYHtyfQojUGFyYW7DoQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBQYXJhbsOhIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9wcl8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUFIiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3ByXzIwMjAgPC0gY292aWRfcHJfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9wcl9yZXN1bW8gPC0gY292aWRfcHJfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wcl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXJhbsOhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wcl9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXJhbsOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFJpbyBkZSBKYW5laXJvCiAKYGBge3J9CiMgUmlvIERlIEphbmVpcm8gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRvIFJpbyBkZSBKYW5laXJvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9yal8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUkoiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3JqXzIwMjAgPC0gY292aWRfcmpfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9yal9yZXN1bW8gPC0gY292aWRfcmpfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9yal9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gZGUgSmFuZWlybyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcmpfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gUmlvIGRlIEphbmVpcm8gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKCmBgYAoKRXN0YWRvIGRvIFJpbyBHcmFuZGUgZG8gTm9ydGUKCmBgYHtyfQojUmlvIEdyYW5kZSBEbyBOb3J0ZQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIE5vcnRlIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9ybl8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUk4iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3JuXzIwMjAgPC0gY292aWRfcm5fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9ybl9yZXN1bW8gPC0gY292aWRfcm5fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9ybl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gR3JhbmRlIGRvIE5vcnRlIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9ybl9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gR3JhbmRlIGRvIE5vcnRlIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFJvbmTDtG5pYQoKYGBge3J9CiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFJvbmTDtG5pYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcm9fMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJPIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9yb18yMDIwIDwtIGNvdmlkX3JvXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcm9fcmVzdW1vIDwtIGNvdmlkX3JvXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcm9fcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9uZMO0bmlhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9yb19yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBSb25kw7RuaWEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKCmBgYAoKRXN0YWRvIGRvIFJvcmFpbWEKCgpgYGB7cn0KI1JvcmlhbWEKIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgUm9yYWltYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcnJfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJSIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9ycl8yMDIwIDwtIGNvdmlkX3JyXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcnJfcmVzdW1vIDwtIGNvdmlkX3JyXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnJfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9yYWltYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnJfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9yYWltYSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCkVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIFN1bAoKYGBge3J9CiNSaW8gR3JhbmRlIERvIFN1bAojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIFN1bCBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcnNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJTIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9yc18yMDIwIDwtIGNvdmlkX3JzXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcnNfcmVzdW1vIDwtIGNvdmlkX3JzXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gUmlvIEdyYW5kZSBkbyBTdWwgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3JzX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIFJpbyBHcmFuZGUgZG8gU3VsIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFNhbnRhIENhdGFyaW5hCgpgYGB7cn0KI1NhbnRhIENhdGFyaW5hCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFNhbnRhIENhdGFyaW5hIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9zY18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiU0MiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3NjXzIwMjAgPC0gY292aWRfc2NfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9zY19yZXN1bW8gPC0gY292aWRfc2NfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zY19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTYW50YSBDYXRhcmluYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfc2NfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gU2FudGEgQ2F0YXJpbmEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gU2VyZ2lwZQoKYGBge3J9CiMgU2VyZ2lwZQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkZSBTZXJnaXBlIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9zZV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiU0UiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3NlXzIwMjAgPC0gY292aWRfc2VfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9zZV9yZXN1bW8gPC0gY292aWRfc2VfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zZV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTZXJnaXBlIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zZV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTZXJnaXBlIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFPDo28gUGF1bG8KCmBgYHtyfQojIFPDo28gUGF1bG8gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFPDo28gUGF1bG8gZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX3NwXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJTUCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfc3BfMjAyMCA8LSBjb3ZpZF9zcF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX3NwX3Jlc3VtbyA8LSBjb3ZpZF9zcF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3NwX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IGVtIFPDo28gUGF1bG8gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3NwX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIFPDo28gUGF1bG8gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgoKRXN0YWRvIGRvIFRvY2FudGlucwoKYGBge3J9CiNUb2NhbnRpbnMKIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgVG9jYW50aW5zIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF90b18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiVE8iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3RvXzIwMjAgPC0gY292aWRfdG9fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF90b19yZXN1bW8gPC0gY292aWRfdG9fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF90b19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBUb2NhbnRpbnMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3RvX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIFRvY2FudGlucyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCgo=